<?php
/**
 * 图片仓库类
 * @author yagas<yagas@163.com>
 * @version 0.4
 * @package CModel
 */
class Storage extends CModel {
    public $filePath;
    public $fileName;
    public $thumbEnable = false;
    private $_instance;
    private $_collection;
    
    /**
     * 初始化Storage容器对象
     */
    public function init() {
        $this->_instance = Yii::app()->mongodb->selectCollection( $this->_collection );
    }
    
    /**
     * 构造函数
     */
    public function __construct( $collection='images' ) {
        $this->_collection = $collection;
        $this->init();
    }
    
    /**
     * 写数据
     * @param CUploadedFile $uploadfile Yii的文件上传对象
     * @return array
     */
    public function writeData( ImageData $imageData ) {
        //如果图片已经存在，直接返回图片ID
        $data = $this->_instance->findOne( array("md5"=>$imageData->md5) );
        if( !is_null($data) ) {
            return array('err'=>null,'_id'=>$data['_id']);
        }

        $result = $this->_instance->insert( $imageData->toArray() );
        if( is_null($result['err']) ) {
            $result['_id'] = $imageData->_id->{'$id'};
        }
        return $result;
    }
    
    /**
     * 读数据
     * @param string $uuid 数据的ID值
     * @return mixd
     */
    public function readData( $uuid ) {
        return $this->_instance->findOne( array("_id"=>new MongoId($uuid)) );
    }
    
    /**
     * 数据查询
     */
    public function find( $optional ) {
        return $this->_instance->find( $optional );
    }
    
    /**
     * 按规格生成图片缩略图
     * @param mongoRecord $data
     */
    public function thumb( $id ) {
        $image = $this->readData( $id );
        if( is_null( $image ) ) {
            return false;
        }
        
    	$collection = Yii::app()->mongodb->selectCollection('thumbs');
    	$result     = $collection->find();
    	if( $result ) {
    		$thumb   = new Thumb( $image['data']->bin );
    		
    		foreach ( $result as $item ) {
    			$bin  = $thumb->zoom( $item['width'] ) ;
    			$data = new ImageData( new MongoBinData( $bin, MongoBinData::GENERIC ) );
                $data->setThumb( $item['width'] );
                $data->fatherId( (string)$image['_id']->{'$id'} );
    			$result = $this->writeData( $data );
    		}
    	}
    }
    
    public function attributeNames() {
        return array('writeData','readData','Thumb');
    }
}

/**
 * MongoDB图片数据
 */
class ImageData {
    // private $_isThumb = false;
    // private $_imageBin;
    private $_imageBinData;
    private $_mimeType = 'image/jpeg';

    /**
     * 数据初始化操作
     */
    public function __construct( $image ) {

        if( !($image instanceof MongoBinData) ) {
            $image = new MongoBinData( file_get_contents( $image ), MongoBinData::GENERIC );
            $this->_mimeType = $this->mime( $image );
        }

        $this->_imageBinData = array(
            '_id'      => new MongoId(),
            'mimeType' => $this->_mimeType,
            'md5'      => md5( $image->bin ),
            'date'     => new MongoDate( time() ),
            'data'     => $image,
        );
    }

    /**
     * 访问属性内容
     */
    public function __get( $key ) {
        if( array_key_exists($key, $this->_imageBinData) ) {
            return $this->_imageBinData[ $key ];
        }
        return;
    }

    /**
     * 数据转为数组的格式
     */
    public function toArray() {
        return $this->_imageBinData;
    }

    /**
     * 设置缩略图的宽度
     */
    public function setThumb( $width ) {
        $this->_imageBinData['thumb'] = $width;
    }

    /**
     * 设置缩略图的父类ID
     */
    public function fatherId( $id ) {
        $this->_imageBinData['fatherId'] = $id;
    }

    /**
     * 文件类型检测
     * @param string $filePath 要进行类型检测的文件路径
     * @return string|Exception
     */
    private function mime( $filePath ) {
        if( file_exists($filePath) ) {
            $file = fopen($filePath, "rb");
            $bin = fread($file, 2); //只读2字节
            fclose($file);
            $strInfo = @unpack("C2chars", $bin);
            $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
            $fileType = '';
            switch ($typeCode) {
                case 8297:
                    $fileType   = 'rar';
                    break;

                case 255216:
                    $fileType = 'image/jpeg';
                    break;

                case 7173:
                    $fileType   = 'image/gif';
                    break;

                case 6677:
                    $fileType   = 'image/bmp';
                    break;

                case 13780:
                    $fileType  = 'image/png';
                    break;

                default:
                    throw new CException('Unknow Mime Type');
            }
            return $fileType;
        }
    }
}